/*
 * Copyright (c) 2010-11 Dropbox, Inc.
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */


package com.kr.aia.powerrp.dropbox;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Environment;
import android.util.Log;
import android.widget.ImageView;
import android.widget.Toast;

import com.dropbox.client2.DropboxAPI;
import com.dropbox.client2.ProgressListener;
import com.dropbox.client2.DropboxAPI.DropboxFileInfo;
import com.dropbox.client2.DropboxAPI.Entry;
import com.dropbox.client2.DropboxAPI.ThumbFormat;
import com.dropbox.client2.DropboxAPI.ThumbSize;
import com.dropbox.client2.exception.DropboxException;
import com.dropbox.client2.exception.DropboxIOException;
import com.dropbox.client2.exception.DropboxParseException;
import com.dropbox.client2.exception.DropboxPartialFileException;
import com.dropbox.client2.exception.DropboxServerException;
import com.dropbox.client2.exception.DropboxUnlinkedException;
import com.kr.aia.powerrp.db.ClosingDBUtil;
import com.kr.aia.powerrp.db.ClosingInfoVO;
import com.kr.aia.powerrp.dropbox.DropBoxLocalListView.VideoDataStruct;
import com.kr.aia.powerrp.roleplay.RPDataVO;

/**
 * Here we show getting metadata for a directory and downloading a file in a
 * background thread, trying to show typical exception handling and flow of
 * control for an app that downloads a file from Dropbox.
 */

public class DropBoxDownload extends AsyncTask<Void, Long, Boolean> {
	private static final String TAG = "TARP";
    private Context mContext;
    private final ProgressDialog mDialog;
    private DropboxAPI<?> mApi;
    private String mPath;
    private ArrayList<String> mFileList;
    private ArrayList<String> mDownloadedFileList;
    private DropBoxLocalListView mLocalListViewAdpater;
    
    private String mCurFile;
    private int mCurIdx;

    private FileOutputStream mFos;

    private boolean mCanceled;
    private Long mFileLen;
    private String mErrorMsg;
    
    // Closing 파일 다운로드 시 DB처리를 위한 객체들
    private ClosingDBUtil closingDataSource;
	private ArrayList<ClosingInfoVO> closingData;

    // Note that, since we use a single file name here for simplicity, you
    // won't be able to use this code for two simultaneous downloads.

    public DropBoxDownload(Context context, DropboxAPI<?> api, String dropboxPath, ArrayList<String> fileName, DropBoxLocalListView localList) {
        // We set the context this way so we don't accidentally leak activities
        mContext = context.getApplicationContext();

        mApi = api;
        mPath = dropboxPath;
        mFileList = fileName;
        mLocalListViewAdpater = localList;
        
        mDownloadedFileList = new ArrayList<String>();
        
        //Log.e("PRP", "PATH : " + mPath + " FILENAME : " + mFileList );

        mDialog = new ProgressDialog(context);
        mDialog.setMessage("Start Downloading File(s)...");
        mDialog.setButton("Cancel", new OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                mCanceled = true;
                mErrorMsg = "Canceled";

                // This will cancel the getThumbnail operation by closing
                // its stream
                if (mFos != null) {
                    try {
                        mFos.close();
                    } catch (IOException e) {
                    }
                }
            }
        });

        mDialog.show();
    }

    @Override
    protected Boolean doInBackground(Void... params) {
        try {
            if (mCanceled) {
                return false;
            }
            
            
            Entry dirent = mApi.metadata(mPath, 1000, null, true, null);
            ArrayList<Entry> metaData = new ArrayList<Entry>();
            
            for (Entry ent: dirent.contents) {
                metaData.add(ent);
            }

            if (metaData.size() == 0) {
                mErrorMsg = "No pictures in that directory";
                return false;
            }

            
            
            for(int i = 0 ; i < mFileList.size(); i++){
            	mCurFile = mFileList.get(i);
        		mCurIdx  = i+1;
        		
        		mDialog.setMax(100);
                mDialog.setProgress(0);
                
            	String cachePath = Environment.getExternalStorageDirectory().getPath() + "/powerRP/txt/rp/" + mFileList.get(i);
            	
            	for (int j = 0 ; j < metaData.size() ; j++) {
            		if(metaData.get(j).fileName().equals(mFileList.get(i))){
            			mFileLen = metaData.get(j).bytes;
            		}
            	}
            	
            	try {
                    mFos = new FileOutputStream(cachePath);
                    mApi.getFile(mPath + mFileList.get(i), null, mFos, 
                    		new ProgressListener() {
		                        @Override
		                        public long progressInterval() {
		                            // Update the progress bar every half-second or so
		                            return 500;
		                        }
		
		                        @Override
		                        public void onProgress(long bytes, long total) {
		                            publishProgress(bytes);
		                        }
                    		}
                    );
                    
                    // closing 파일일 경우 Array에 담아두었다가 처리.
                    if(mFileList.get(i).startsWith("closing")){
                    	Log.e(TAG, "DropBox File Downloaded. File Name = " + mFileList.get(i));
                    	mDownloadedFileList.add(mFileList.get(i));
                    }
                    
                    
                    if (mCanceled) {
                        return false;
                    }
                } catch (FileNotFoundException e) {
                    mErrorMsg = "Couldn't create a local file to store the image";
                    return false;
                } finally{
                	if(mFos != null){
                		try{
                			mFos.close();
                		}catch (IOException e){
                			mErrorMsg = "Couldn't create a local file to store the image";
                		}
                	}
                }

                // This downloads a smaller, thumbnail version of the file.  The
                // API to download the actual file is roughly the same.
                
            }
            return true;

        } catch (DropboxUnlinkedException e) {
            // The AuthSession wasn't properly authenticated or user unlinked.
        } catch (DropboxPartialFileException e) {
            // We canceled the operation
            mErrorMsg = "Download canceled";
        } catch (DropboxServerException e) {
            // Server-side exception.  These are examples of what could happen,
            // but we don't do anything special with them here.
            if (e.error == DropboxServerException._304_NOT_MODIFIED) {
                // won't happen since we don't pass in revision with metadata
            } else if (e.error == DropboxServerException._401_UNAUTHORIZED) {
                // Unauthorized, so we should unlink them.  You may want to
                // automatically log the user out in this case.
            } else if (e.error == DropboxServerException._403_FORBIDDEN) {
                // Not allowed to access this
            } else if (e.error == DropboxServerException._404_NOT_FOUND) {
                // path not found (or if it was the thumbnail, can't be
                // thumbnailed)
            } else if (e.error == DropboxServerException._406_NOT_ACCEPTABLE) {
                // too many entries to return
            } else if (e.error == DropboxServerException._415_UNSUPPORTED_MEDIA) {
                // can't be thumbnailed
            } else if (e.error == DropboxServerException._507_INSUFFICIENT_STORAGE) {
                // user is over quota
            } else {
                // Something else
            }
            // This gets the Dropbox error, translated into the user's language
            mErrorMsg = e.body.userError;
            if (mErrorMsg == null) {
                mErrorMsg = e.body.error;
            }
        } catch (DropboxIOException e) {
            // Happens all the time, probably want to retry automatically.
            mErrorMsg = "Network error.  Try again.";
        } catch (DropboxParseException e) {
            // Probably due to Dropbox server restarting, should retry
            mErrorMsg = "Dropbox error.  Try again.";
        } catch (DropboxException e) {
            // Unknown error
            mErrorMsg = "Unknown error.  Try again.";
        }
        return false;
    }

    @Override
    protected void onProgressUpdate(Long... progress) {
        int percent = (int)(100.0*(double)progress[0]/mFileLen + 0.5);
        mDialog.setProgress(percent);
        mDialog.setMessage("Downloading " + mCurFile + " (" + mCurIdx +"/" + mFileList.size() + ")");
    }

    @Override
    protected void onPostExecute(Boolean result) {
        
        if (result) {
        	mLocalListViewAdpater.refreshView();
        	insertClosingData();
        	mDialog.dismiss();
        } else {
            // Couldn't download it, so show an error
            showToast(mErrorMsg);
        }
    }

    private void showToast(String msg) {
        Toast error = Toast.makeText(mContext, msg, Toast.LENGTH_LONG);
        error.show();
    }
    
    private void insertClosingData(){
    	closingDataSource = new ClosingDBUtil(mContext);
        closingDataSource.open();
        
        FileInputStream mFis = null;
        BufferedReader mBr = null;
        ClosingInfoVO tmpClosingVO;
        String strLine, strValue = "";
        
        for(int i = 0 ; i < mDownloadedFileList.size() ; i++){
        	try {
        		mFis = new FileInputStream(Environment.getExternalStorageDirectory().getPath() + "/powerRP/txt/rp/" + mDownloadedFileList.get(i));
        		mBr  = new BufferedReader(new InputStreamReader(mFis));
    			strValue = "";
    			while( (strLine = mBr.readLine()) != null )
    				strValue += strLine + "\n";
    			
    			String fileLabel	= mDownloadedFileList.get(i).substring(0, mDownloadedFileList.get(i).lastIndexOf("."));
    			String tmpSeqno		= fileLabel.substring(7);
    			int seqno = Integer.parseInt(tmpSeqno);
    			
    			tmpClosingVO = new ClosingInfoVO(seqno, fileLabel, strValue);
    			closingDataSource.updateClosingData(tmpClosingVO);
    			
            } catch (IOException e) {
    			Toast.makeText(mContext, mDownloadedFileList.get(i) + " 파일 불러오기 실패.", Toast.LENGTH_SHORT).show(); 
    		}
        }
        
        Toast.makeText(mContext, "Closing 파일을 저장 하였습니다.", Toast.LENGTH_SHORT).show(); 
        closingDataSource.close();
    }


}
